package com.jsonal.service.impl;

import com.alibaba.fastjson.support.odps.udf.CodecCheck.A;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jsonal.common.JsonUtils;
import com.jsonal.entity.api.Article;
import com.jsonal.entity.api.ArticleBean;
import com.jsonal.entity.api.ArticleTags;
import com.jsonal.entity.api.Tags;
import com.jsonal.entity.api.User;
import com.jsonal.mapper.ArticleMapper;
import com.jsonal.mapper.ArticleTagsMapper;
import com.jsonal.mapper.TagsMapper;
import com.jsonal.mapper.api.UserMapper;
import com.jsonal.service.ArticleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jsonal.util.RedisUtil;
import com.jsonal.vo.Result;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author auto
 * @since 2020-04-20
 */
@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements
    ArticleService {

    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private ArticleMapper articleMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private ArticleTagsMapper articleTagsMapper;
    @Autowired
    private TagsMapper tagsMapper;

    /**
     * 发布文章
     *
     * @param articleBean model
     * @return res
     */
    @Override
    public Result releaseBlog(ArticleBean articleBean) {
        Result result = new Result();
        Object obj = redisUtil.get(articleBean.getUsername());
        User user = JsonUtils.jsonToPojo(obj.toString(), User.class);
        if (user != null) {
            Article article = new Article();
            BeanUtils.copyProperties(articleBean, article);
            article.setOpen(Integer.valueOf(articleBean.getOpen()));
            if (articleBean.getId() != null && !"".equals(articleBean.getId())) {
                article.setUpdateTime(new Date());
                articleMapper.updateById(article);
                // 先查询该文章id的原来标签
                List<Tags> tags = tagsMapper
                    .selectList(new QueryWrapper<Tags>().eq("id", article.getId()));
                List<String> tagsList = new ArrayList<>();
                tags.forEach(item -> {
                    tagsList.add(item.getName());
                });
                List<String> strings = updateArticleTags(tagsList, articleBean.getTagsList());
                strings.forEach(item -> {
                    Tags tags1 = tagsMapper.selectOne(new QueryWrapper<Tags>().eq("name", item));
                    // 查询该博客id下的所有标签
                    List<ArticleTags> tagsList1 = articleTagsMapper.selectList(
                        new QueryWrapper<ArticleTags>().eq("article_id", articleBean.getId()));
                    // 循环更新标签状态
                    for (ArticleTags tags2 : tagsList1) {
                        // 满足 标签id 一致  博客 id 一致
                        if (tags1.getGuid().equals(tags2.getTagsId())) {
                            tags2.setTagsId(tags1.getGuid());
                            tags2.setDelFlag(1);
                            tags2.setArticleId(articleBean.getId());
                            tags2.setId(tags1.getId());
                            tags2.setUpdateTime(new Date());
                            articleTagsMapper.updateById(tags2);
                        }
                    }
                });
                result.setMsg("保存成功");
            } else {
                article.setCreateTime(new Date());
                article.setDelFlag(false);
                article.setGiveLikeNum(0);
                article.setToViewNum(0);
                article.setUserId(user.getId());
                int insert = articleMapper.insert(article);
                if (articleBean.getTagsList().size() > 0) {
                    articleBean.getTagsList().forEach(item -> {
                        Tags tags = tagsMapper.selectOne(new QueryWrapper<Tags>().eq("guid", item));
                        ArticleTags articleTags = new ArticleTags();
                        articleTags.setDelFlag(0);
                        articleTags.setTagsId(tags.getGuid());
                        articleTags.setArticleId(insert);
                        articleTags.setCreateTime(new Date());
                        articleTagsMapper.insert(articleTags);
                    });
                }
                result.setMsg("发布成功");
            }
            result.setSuccess(true);
            return result;
        }

        return null;
    }

    /**
     * 更新标签，判断与原本的标签是否有差异 1.与原来的标签一致 2.部分一致，部分不一致 3.完全不同
     *
     * 解决思路：将两个列表整合成一个列表，然后删除旧的列表的数据，然后再循环插入
     * @return 返回待更新的列表
     */
    public List<String> updateArticleTags(List<String> oldTags, List<String> newTags) {
        List<String> list = Stream.of(oldTags, newTags)
            .flatMap(Collection::stream)
            .collect(Collectors.toList());
        list.removeAll(oldTags);

        return list;
    }

    /**
     * 根据用户获取该用户下的所有博客文章
     *
     * @param articleBean model
     * @return res
     */
    @Override
    public Result getMyBlogList(ArticleBean articleBean) {
        Result result = new Result();
        Object obj = redisUtil.get(articleBean.getUsername());
        User user = null;
        if (obj != null) {
            user = JsonUtils.jsonToPojo(obj.toString(), User.class);
            List<Article> articles = articleMapper.selectList(new QueryWrapper<Article>()
                .eq("user_id", user.getId())
                .eq("del_flag", false)
                .orderByDesc("create_time"));
            List<ArticleBean> beans = new ArrayList<>();
            // 根据结果集循环判断是否存在标签
            articles.forEach(item -> {
                ArticleBean bean = new ArticleBean();
                BeanUtils.copyProperties(item, bean);
                // 查询该博客id下的所有tags
                List<ArticleTags> tagsList = articleTagsMapper
                    .selectList(new QueryWrapper<ArticleTags>().eq("article_id", item.getId()));
                // 如果tagsList的数量大于0 表示存在tags
                if (tagsList.size() > 0) {
                    List<String> names = new ArrayList<>();
                    tagsList.forEach(tag -> {
                        // 根据 tagsId 再去tags表中查询name
                        if (tag.getTagsId() != null) {
                            Tags tags = tagsMapper
                                .selectOne(new QueryWrapper<Tags>().eq("guid", tag.getTagsId()));
                            names.add(tags.getName());
                        }
                    });
                    bean.setTagsList(names);
                }
                beans.add(bean);
            });
            result.setSuccess(true);
            result.setResults(beans);
            return result;
        }
        result.setSuccess(false);
        result.setMsg("用户不存在");
        return result;
    }

    /**
     * 查看详细内容
     *
     * @param id model
     * @return res
     */
    @Override
    public Result getBlogInfo(String id) {
        Result result = new Result();
        Article article = articleMapper
            .selectOne(new QueryWrapper<Article>().eq("id", id));
        // 根据文章 id 去查询该 id 下所有的标签列表
        List<ArticleTags> tagsLists = articleTagsMapper
            .selectList(new QueryWrapper<ArticleTags>().eq("article_id", article.getId()));
        ArticleBean bean = new ArticleBean();
        BeanUtils.copyProperties(article, bean);
        List<String> tagsList = new ArrayList<>();
        for (ArticleTags tags: tagsLists) {
            Tags tag = tagsMapper
                .selectOne(new QueryWrapper<Tags>().eq("guid", tags.getTagsId()));
            tagsList.add(tag.getName());
        }
        bean.setTagsList(tagsList);
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("id", article.getUserId()));
        bean.setUsername(user.getUsername());
        result.setObj(bean);
        result.setSuccess(true);
        return result;
    }

    /**
     * 根据 id 逻辑删除数据
     *
     * @param id 文章 id
     * @return res
     */
    @Override
    public Result remove(String id) {
        Result result = new Result();
        Article article = articleMapper
            .selectOne(new QueryWrapper<Article>().eq("id", id).eq("del_flag", false));
        if (article == null) {
            return new Result(false, "文章不存在");
        }
        article.setDelFlag(true);
        article.setUpdateTime(new Date());
        articleMapper.updateById(article);
        result.setMsg("删除成功");
        result.setSuccess(true);
        return result;
    }

    /**
     * 更新数据
     *
     * @param articleBean model
     * @return res
     */
    @Override
    public Result updateInfo(ArticleBean articleBean) {
        Result result = new Result();
        Article article = new Article();
        BeanUtils.copyProperties(articleBean, article);
        article.setUpdateTime(new Date());
        articleMapper.updateById(article);
        result.setSuccess(true);
        result.setMsg("更新成功");
        return result;
    }

    /**
     * 首页展示数据
     *
     * @param articleBean 分页
     * @return res
     */
    @Override
    public Result getBlogList(ArticleBean articleBean) {
        Result result = new Result();
        Page<Article> page = new Page<>(1, 10);
        IPage<Article> articles = articleMapper.selectPage(page,
            new QueryWrapper<Article>()
                .eq("del_flag", false)
                .and(i-> i.eq("open", 0))
                .orderByDesc("create_time"));
        List<ArticleBean> beans = new ArrayList<>();
        // 根据结果集循环判断是否存在标签
        articles.getRecords().forEach(item -> {
            ArticleBean bean = new ArticleBean();
            BeanUtils.copyProperties(item, bean);
            // 查询该博客id下的所有tags
            List<ArticleTags> tagsList = articleTagsMapper
                .selectList(new QueryWrapper<ArticleTags>().eq("article_id", item.getId()));
            // 如果tagsList的数量大于0 表示存在tags
            if (tagsList.size() > 0) {
                List<String> names = new ArrayList<>();
                tagsList.forEach(tag -> {
                    // 根据 tagsId 再去tags表中查询name
                    Tags tags = tagsMapper
                        .selectOne(new QueryWrapper<Tags>().eq("guid", tag.getTagsId()));
                    names.add(tags.getName());
                });
                bean.setTagsList(names);
            }
            beans.add(bean);
        });
        result.setSuccess(true);
        result.setResults(beans);
        return result;
    }

    /**
     * 获取文章列表（后台）
     *
     * @param articleBean model
     * @return res
     */
    @Override
    public Result getArticleList(ArticleBean articleBean) {
        Result result = new Result();
        List<ArticleBean> beans = new ArrayList<>();
        IPage<Article> page = new Page<Article>(articleBean.getPage(), articleBean.getPageSize());
        IPage<Article> articles = null;
        if (articleBean.getQuery() != null && !"".equals(articleBean.getQuery())) {
            articles = articleMapper
                .selectPage(page, new QueryWrapper<Article>()
                    .eq("del_flag", false)
                    .and(i -> i.like("title", articleBean.getQuery()))
                );
        } else {
            articles = articleMapper
                .selectPage(page, new QueryWrapper<Article>().eq("del_flag", false));
        }
        articles.getRecords().forEach(item -> {
            ArticleBean bean = new ArticleBean();
            BeanUtils.copyProperties(item, bean);
            User user = userMapper.selectById(item.getUserId());
            bean.setUsername(user.getUsername());
            beans.add(bean);
        });
        if (beans.size() > 0) {
            result.setSuccess(true);
            result.setResults(beans);
            result.setObj(articles);
            return result;
        }
        result.setSuccess(false);
        return result;
    }

    /**
     * 根据 id 设置为热门文章
     *
     * @param id id
     * @return res
     */
    @Override
    public Result hot(String id) {
        Result result = new Result();
        Article article = articleMapper
            .selectOne(new QueryWrapper<Article>().eq("id", id).eq("del_flag", false));
        if (article == null) {
            return new Result(false, "该 id 不存在");
        }
        article.setStatus("1");
        article.setUpdateTime(new Date());
        int update = articleMapper.updateById(article);
        if (update > 0) {
            result.setSuccess(true);
            result.setMsg("设置成功");
            return result;
        }
        return new Result(false, "设置失败");
    }

    /**
     * 获取热门文章
     *
     * @return res
     */
    @Override
    public Result getHotList() {
        Result result = new Result();
        List<Article> articles = articleMapper
            .selectList(new QueryWrapper<Article>()
                .eq("status", 1)
                .eq("del_flag", false)
                .orderByDesc("id")
            );
        if (articles.size() > 0) {
            result.setSuccess(true);
            result.setResults(articles);
            return result;
        }
        return new Result(false, "没有热门文章");
    }
}
